package xin.altitude.spring.mybatisplus.joinquery.one2more.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import xin.altitude.common.service.impl.ServiceImpl;
import xin.altitude.common.util.ColOptional;
import xin.altitude.common.util.EntityUtils;
import xin.altitude.common.util.PageOptional;
import xin.altitude.spring.mybatisplus.joinquery.one2more.entity.Dept;
import xin.altitude.spring.mybatisplus.joinquery.one2more.entity.User;
import xin.altitude.spring.mybatisplus.joinquery.one2more.entity.vo.UserVo;
import xin.altitude.spring.mybatisplus.joinquery.one2more.mapper.UserMapper;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;

import static java.util.stream.Collectors.toSet;

/**
 * 一个用户对应一个部门
 *
 * @Author explore
 * @Date 2021/05/24 11:09
 **/
@Service
public class UserProService extends ServiceImpl<UserMapper, User> {
    
    @Autowired
    private DeptService deptService;
    
    /**
     * 查询单个学生信息（一个学生对应一个部门）
     */
    public UserVo getOneUser(Integer userId) {
        UserVo userVo = getById(userId, UserVo::new);
        Optional.ofNullable(userVo).ifPresent(this::addDetpNameInfo);
        return userVo;
    }
    
    /**
     * 补充部门名称信息
     */
    private void addDetpNameInfo(UserVo userVo) {
        LambdaQueryWrapper<Dept> wrapper = Wrappers.lambdaQuery(Dept.class).eq(Dept::getDeptId, userVo.getDeptId());
        Dept dept = deptService.getOne(wrapper);
        Optional.ofNullable(dept).ifPresent(e -> userVo.setDeptName(e.getDeptName()));
    }
    
    /**
     * 批量查询学生信息（一个学生对应一个部门）
     */
    public List<UserVo> getUserByList() {
        List<UserVo> userVos = list(UserVo::new);
        ColOptional.of(userVos).ifNotEmpty(this::addDeptNameInfo);
        return userVos;
    }
    
    private void addDeptNameInfo(List<UserVo> userVos) {
        // 提取用户userId，方便批量查询
        Set<Integer> deptIds = EntityUtils.collectList(userVos, User::getDeptId, toSet());
        // 根据deptId查询deptName（查询前，先做非空判断）
        LambdaQueryWrapper<Dept> wrapper = Wrappers.lambdaQuery(Dept.class).in(Dept::getDeptId, deptIds);
        // 构造映射关系，方便匹配deptId与deptName
        Map<Integer, String> hashMap = deptService.map(wrapper, Dept::getDeptId, Dept::getDeptName);
        // 封装Vo，并添加到集合中(关键内容)
        userVos.forEach(e -> e.setDeptName(hashMap.get(e.getDeptId())));
    }
    
    private void addDeptNameInfo2(List<UserVo> userVos) {
        // 提取用户userId，方便批量查询
        Set<Integer> deptIds = EntityUtils.collectList(userVos, User::getDeptId, toSet());
        Map<Integer, String> hashMap = deptService.mapByIds(deptIds, Dept::getDeptId, Dept::getDeptName);
        // 封装Vo，并添加到集合中(关键内容)
        userVos.forEach(e -> e.setDeptName(hashMap.get(e.getDeptId())));
    }
    
    
    /**
     * 分页查询学生信息（一个学生对应一个部门）
     */
    public IPage<UserVo> getUserByPage(Page<User> page) {
        IPage<UserVo> userVoPage = page(page, UserVo::new);
        PageOptional.of(userVoPage).ifRecordNotEmpty(this::addDeptNameInfo);
        return userVoPage;
    }
    
    private void addDeptNameInfo(IPage<UserVo> userVoPage) {
        // 提取用户userId，方便批量查询
        Set<Integer> deptIds = EntityUtils.collectList(userVoPage.getRecords(), User::getDeptId, toSet());
        // 根据deptId查询deptName
        LambdaQueryWrapper<Dept> wrapper = Wrappers.lambdaQuery(Dept.class).in(Dept::getDeptId, deptIds);
        // 构造映射关系，方便匹配deptId与deptName
        Map<Integer, String> hashMap = deptService.map(wrapper, Dept::getDeptId, Dept::getDeptName);
        // 将查询补充的信息添加到Vo中
        userVoPage.convert(e -> e.setDeptName(hashMap.get(e.getDeptId())));
    }
}
